package seatiger.tomcat.catalina.connector;

import seatiger.tomcat.coyote.Response;
import seatiger.tomcat.util.buf.ByteChunk;

import java.io.IOException;

/**
 * 用于tomcat的输出缓冲
 */
public class OutputBuffer implements ByteChunk.ByteOutputChannel {

    private ByteChunk bb;

    /**
     * 真正用于写出对象的字节块对象
     */
    private ByteChunk outputChunk = new ByteChunk();

    /**
     * 关联的coyoteResponse
     */
    private Response coyoteResponse;

    /**
     * 关闭的标志
     */
    private boolean closed = false;

    public void setResponse(Response coyoteResponse) {
        this.coyoteResponse = coyoteResponse;
    }

    public OutputBuffer(int size) {
        bb = new ByteChunk(size);
        bb.setByteOutputChannel(this);
        bb.setLimit(size);
    }

    public void write(byte b[], int off, int len) throws IOException {
        writeBytes(b, off, len);
    }

    private void writeBytes(byte[] b, int off, int len) throws IOException {
        bb.append(b, off, len);
    }

    @Override
    public void realWriteBytes(byte[] cbuf, int off, int cnt) throws IOException {
        if (closed) {
            return;
        }
        if (cnt > 0) {
            outputChunk.setBytes(cbuf, off, cnt);
            coyoteResponse.doWrite(outputChunk);
        }
    }

    public void close() throws IOException{
        if (closed) {
            return;
        }
        if (!coyoteResponse.isCommited() && coyoteResponse.getContentLength() == -1){
            //设置发送长度
            coyoteResponse.setContentLength(bb.getLength());
        }
        doFlush();
        closed = true;
        coyoteResponse.finish();
    }

    protected void doFlush() throws IOException {
        //发送报文头信息
        coyoteResponse.sendHeaders();
        if (bb.getLength() > 0) {
            //一般为报文体中内容刷出
            bb.flushBuffer();
        }
    }

}
